package com.hgc.ch02.forkjoin;

import com.hgc.ch02.sort.SortUtil;
import com.hgc.ch02.tool.MakeArray;

import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * Created by 01367627 on 2019/7/8.
 */
public class FJSort {

    private static class SumTask extends RecursiveTask<int[]> {

        private static final int THRESHOLD = 2;
        private int[] src;

        public SumTask(int[] src) {
            this.src = src;
        }

        @Override
        protected int[] compute() {
            if (src.length <= THRESHOLD) {
                return SortUtil.insertionSort(src);
            } else {
                int mid = src.length / 2;
                SumTask leftTask = new SumTask(Arrays.copyOfRange(src, 0, mid));
                SumTask rightTask = new SumTask(Arrays.copyOfRange(src, mid, src.length));
                invokeAll(leftTask, rightTask);
                int[] leftJoin = leftTask.join();
                int[] rightJoin = rightTask.join();
                return SortUtil.merge(leftJoin, rightJoin);
            }
        }
    }

    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        int size = 40000000;
        int[] src = MakeArray.makeArray(size);
        SumTask sumTask = new SumTask(src);
        long start = System.currentTimeMillis();
        int[] result = pool.invoke(sumTask);
        System.out.println("FJ排序" + size + "数据花费时间：" + (System.currentTimeMillis() - start) + "ms");
        SortUtil.print(result);
        System.out.println();
        start = System.currentTimeMillis();
        result = SortUtil.mergeSort(src);
        System.out.println("归并排序" + size + "数据花费时间：" + (System.currentTimeMillis() - start) + "ms");
        SortUtil.print(result);
        System.out.println();
        start = System.currentTimeMillis();
        result = SortUtil.quickSort(src, 0, src.length - 1);
        System.out.println("快速排序" + size + "数据花费时间：" + (System.currentTimeMillis() - start) + "ms");
        SortUtil.print(result);
    }
}
